<?php
/**
 * Note:     [Description]
 * Author:   longhui.huang <1592328848@qq.com>
 * DateTime: 2024/2/7 16:21
 */
declare(strict_types=1);

namespace App\Service;

use App\Bean\MenuMetaVoBean;
use App\Bean\MenuVoBean;
use App\Dao\MenuDao;
use App\Model\MenuModel;
use App\Model\UserModel;

class MenuService extends BaseService
{
    public function build(UserModel $userModel)
    {
        $menuList = $this->findByUser($userModel->userId);
        $menus    = $this->buildTree($menuList);
        return $this->buildMenus($menus);
    }

    /**
     * 根据当前用户获取菜单
     *
     * @param int $currentUserId
     */
    public function findByUser(int $currentUserId)
    {
        /** @var RoleService $roleService */
        $roleService = app(RoleService::class);
        $roles       = $roleService->findByUserId($currentUserId);
        $roleIds     = [];

        foreach ($roles as $role) {
            $roleIds[] = $role['roleId'];
        }

        if (!$roleIds) {
            return [];
        }

        $roleIds = array_unique($roleIds);

        /** @var MenuDao $menuDao */
        $menuDao = app(MenuDao::class);
        return $menuDao->findByRoleIdsAndTypeNot($roleIds, 2);
    }

    /**
     * 构建菜单树
     *
     * @param MenuModel[] $menus 原始数据
     */
    public function buildTree(array $menus)
    {
        $trees = [];
        $ids   = [];
        foreach ($menus as $menu) {
            if (!$menu->pid) {
                $trees[] = $menu;
            }

            foreach ($menus as $it) {
                if ($menu->menuId == $it->pid) {
                    if (!$menu->children) {
                        $menu->setAttr('children', []);
                    }
                    $children   = $menu->children;
                    $children[] = $it;
                    $menu->setAttr('children', $children);
                    $ids[] = $it->menuId;
                }
            }
        }

        if (count($trees) === 0) {
            foreach ($menus as $s) {
                if (!in_array($s->menuId, $ids)) {
                    $trees[] = $s;
                }
            }
        }

        return $trees;
    }

    /**
     * 构建菜单树
     *
     * @param MenuModel[] $menus
     *
     * @return array
     */
    public function buildMenus(array $menus): array
    {
        $list = [];
        foreach ($menus as $menu) {
            $menuList = $menu->children;
            $menuVo   = new MenuVoBean();
            $name     = $menu->name ? $menu->name : $menu->title;
            $menuVo->setName($name);
            // 一级目录需要加斜杠，不然会报警告
            $path = $menu->pid ? $menu->path : "/" . $menu->path;
            $menuVo->setPath($path);
            $menuVo->setHidden($menu->hidden);

            // 如果不是外链
            if (!$menu->iFrame) {
                $component = null;
                if (!$menu->pid) {
                    $component = $menu->component ? $menu->component : 'Layout';
                } else if ($menu->type === 0) {
                    // 如果不是一级菜单，并且菜单类型为目录，则代表是多级菜单
                    $component = $menu->component ? $menu->component : 'ParentView';
                } else if ($menu->component) {
                    $component = $menu->component;
                }

                $menuVo->setComponent($component);
            }

            $menuMetaVoBean = new MenuMetaVoBean();
            $menuMetaVoBean->setTitle($menu->title);
            $menuMetaVoBean->setIcon($menu->icon);
            $menuMetaVoBean->setNoCache(!$menu->cache);
            $menuVo->setMeta($menuMetaVoBean);

            if (!empty($menuList)) {
                $menuVo->setAlwaysShow(true);
                $menuVo->setRedirect('noredirect');
                $menuVo->setChildren($this->buildMenus($menuList));
                // 处理是一级菜单并且没有子菜单的情况
            } else if (!$menu->pid) {
                $menuVo1 = new MenuVoBean();
                $menuVo1->setMeta($menuVo->getMeta());

                // 非外链
                if (!$menu->iFrame) {
                    $menuVo1->setPath('index');
                    $menuVo1->setName($menuVo->getName());
                    $menuVo1->setComponent($menuVo->getComponent());
                } else {
                    $menuVo1->setPath($menu->path);
                }

                $menuVo->setName(null);
                $menuVo->setMeta(null);
                $menuVo->setComponent('Layout');
                $list1   = [];
                $list1[] = $menuVo1;
                $menuVo->setChildren($list1);
            }

            $list[] = $menuVo;
        }

        return $list;
    }
}
